package com.cj.sys.service.security;

import java.util.Set;

import org.dom4j.Document;
import org.dom4j.DocumentHelper;
import org.dom4j.Element;
import org.springframework.beans.factory.FactoryBean;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.security.intercept.web.FilterInvocationDefinitionSource;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import com.cj.common.orm.hibernate.EntityManager;
import com.cj.common.orm.hibernate.HibernateDao;
import com.cj.common.security.springsecurity.FilterSecurityInterceptor;
import com.cj.common.utils.TreeUtil;
import com.cj.sys.dao.security.ResourceDao;
import com.cj.sys.dao.security.UserDao;
import com.cj.sys.entity.security.Resource;
import com.cj.sys.service.ServiceException;

//Spring Service Bean的标识.
@Service
// 默认将类中的所有函数纳入事务管理.
@Transactional
public class ResourceManager extends EntityManager<Resource, Long> {
	@Autowired
	private ResourceDao resourceDao;
	@Autowired
	private FilterSecurityInterceptor filterSecurityInterceptor;
	@Autowired
	private UserDao userDao;
	@Autowired
	@Qualifier("databaseDefinitionSource")	
	private FactoryBean databaseDefinitionSource;
	
	@Override
	protected HibernateDao<Resource, Long> getEntityDao() {
		return resourceDao;
	}
	
	@Override
	protected void afterChange(Resource entity) {
		try {
			filterSecurityInterceptor.setObjectDefinitionSource((FilterInvocationDefinitionSource)databaseDefinitionSource.getObject());
		} catch (Exception e) {
			logger.error("更新权限错误!",e);
		}
	}
	
	@Transactional(readOnly = true)
	public String getMenuXmlTree(Long userId,Long parentId)throws Exception {
		try {
			Document doc = DocumentHelper.createDocument();
			doc.setXMLEncoding("UTF-8");
			Element root = doc.addElement("TreeNode");
			Set<Resource> resources = userDao.getResources(userId);
			getXMLElement(root,resources,parentId);
			return doc.asXML();
		} catch (Exception e) {
			logger.error(e.getMessage(), e);
			throw new ServiceException(
					"getMenuXmlTree Error!" + e.getMessage(), e);
		}
	}
	
	private void getXMLElement(Element root,Set<Resource> resources,Long parentId){
		if(parentId == null){
			parentId = 1L;
		}
		int i = 0;
		while(!resources.isEmpty() && i < resources.size()){
			Resource resource = (Resource)resources.toArray()[i++];
			if(parentId.equals(resource.getParent().getId()) && !parentId.equals(resource.getId())){
				Element element = TreeUtil.getElement(root, resource, "name", "id");
				resources.remove(resource);
				i=0;
				getXMLElement(element, resources, resource.getId());
			}
		}
	}
}
